#pragma once

#ifndef _DBCONNECTIONPOOL_H_
#define _DBCONNECTIONPOOL_H_
#include "EventLoop.h"
#include <chrono>
#include <cppconn/connection.h>
#include <type_traits>
#include <vector>
#include <cppconn/mysql_driver.h>
#include <queue>
#include <condition_variable>
#include <mutex>
#include <set>
#include <thread>
#include <atomic>

namespace SOS{



class DbConnectionPool
{
public:
    
    static DbConnectionPool & getInstance();
    sql::Connection* getConnection(int timeoutMs = 500);//获取连接(阻塞或超时)
    void releaseConnection(sql::Connection*);//释放连接
    //单例下禁用拷贝构造与赋值运算符函数
    DbConnectionPool(const DbConnectionPool &) = delete;
    DbConnectionPool &operator=(const DbConnectionPool &) = delete;
private:
    DbConnectionPool();
    ~DbConnectionPool();
    sql::Connection* createNewConnection();
    void loadConfig();
    void recycleIdleConnections();
    bool validateConnection(sql::Connection*);
private:
    struct ConnectionMeta{
        sql::Connection *_conn;
        std::chrono::system_clock::time_point _lastused;
    };

    std::string _url;
    std::string _user;
    std::string _passwd;
    int _initSize,_maxSize,_maxIdleTimesSec;
    std::queue<ConnectionMeta> _idleConns;//空闲连接
    std::set<sql::Connection*> _activeConns;//活跃连接
    std::mutex _mutex;
    std::condition_variable _cond;
    std::atomic<bool> _stopRecycling;
    std::thread _recycleThread;

};


} // namespace SOS;

#endif

